package gr.atc.epart;

import gr.atc.epart.actions.Action.Type;
import gr.atc.epart.net.ActionsPage.SortBy;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;

public class CustomCategoriesManager
{
	public class CustomTabData
	{
		private String		_tabName;
		private Type		_actionType;
		private String		_creator;
		private Date		_startDate;
		private Date		_stopDate;
		private String[]	_tags;
		private SortBy		_sortBy;
		private int			_pageNumber;
		private int			_pageSize;

		public CustomTabData()
		{
		}

		public CustomTabData(String tabName, Type actionType, String creator,
				Date startDate, Date stopDate, String[] tags, SortBy sortBy,
				int pageNumber, int pageSize)
		{
			_tabName = tabName;
			_actionType = actionType;
			_creator = creator;
			_startDate = startDate;
			_stopDate = stopDate;
			_tags = tags;
			_sortBy = sortBy;
			_pageNumber = pageNumber;
			_pageSize = pageSize;
		}

		public String getTabName()
		{
			return _tabName;
		}

		public void setTabName(String name)
		{
			_tabName = name;
		}

		public Type getActionType()
		{
			return _actionType;
		}

		public void setActionType(Type type)
		{
			_actionType = type;
		}

		public String getCreator()
		{
			return _creator;
		}

		public void setCreator(String _creator)
		{
			this._creator = _creator;
		}

		public Date getStartDate()
		{
			return _startDate;
		}

		public void setStartDate(Date date)
		{
			_startDate = date;
		}

		public Date getStopDate()
		{
			return _stopDate;
		}

		public void setStopDate(Date date)
		{
			_stopDate = date;
		}

		public String[] getTags()
		{
			return _tags;
		}

		public void setTags(String[] tags)
		{
			_tags = tags;
		}

		public SortBy getSortBy()
		{
			return _sortBy;
		}

		public void setSortBy(SortBy by)
		{
			_sortBy = by;
		}

		public int getPageNumber()
		{
			return _pageNumber;
		}

		public void setPageNumber(int number)
		{
			_pageNumber = number;
		}

		public int getPageSize()
		{
			return _pageSize;
		}

		public void setPageSize(int size)
		{
			_pageSize = size;
		}

	}

	private JSONObject	_customCategories;
	private Activity _context;

	public CustomCategoriesManager(Activity context)
	{
		_context = context;
		loadFromDisk();
		
	}

	public boolean addCustomTab(String tabName, Type actionType,
			String creator, Date startDate, Date stopDate, String tags,
			SortBy sortBy, int pageNumber, int pageSize)
	{
		try
		{
			
			//
			// get the existing categories array, or create it if this is the
			// first call
			//
			if (!_customCategories.has("categories"))
				_customCategories.put("categories", new JSONArray());

			JSONArray categories = _customCategories.getJSONArray("categories");

			//
			// create a JSON object with all the query parameters
			//
			JSONObject tabData = createTabData(tabName, actionType, creator,
					startDate, stopDate, tags, sortBy, 1, 50);

			if (tabData != null)
			{
				// TODO:: check for duplicates before adding a new one
				categories.put(tabData);
				saveToDisk();
				return true;
			}
			else
			{
				return false;
			}

		} catch (JSONException e)
		{
			e.printStackTrace();
			return false;
		}
	}
	
	public boolean addCustomTab(String tabName, Type actionType,
			String creator, String startDate, String stopDate, String tags,
			SortBy sortBy, int pageNumber, int pageSize)
	{
		try
		{
			
			//
			// get the existing categories array, or create it if this is the
			// first call
			//
			if (!_customCategories.has("categories"))
				_customCategories.put("categories", new JSONArray());

			JSONArray categories = _customCategories.getJSONArray("categories");

			//
			// create a JSON object with all the query parameters
			//
			JSONObject tabData = createTabData(tabName, actionType, creator,
					startDate, stopDate, tags, sortBy, 1, 50);

			if (tabData != null)
			{
				// TODO:: check for duplicates before adding a new one
				categories.put(tabData);
				saveToDisk();
				return true;
			}
			else
			{
				return false;
			}

		} catch (JSONException e)
		{
			e.printStackTrace();
			return false;
		}
	}
	
	public boolean updateCustomTab(String tabName, Type actionType,
			String creator, Date startDate, Date stopDate, String tags,
			SortBy sortBy, int pageNumber, int pageSize)
	{
		if (existsTab(tabName))
		{
			if (!removeCustomTab(tabName))
				return false;
		}

		return addCustomTab(tabName, actionType, creator, startDate, stopDate, tags, sortBy, pageNumber, pageSize);
	}
	
	public boolean updateCustomTab(String tabName, Type actionType,
			String creator, String startDate, String stopDate, String tags,
			SortBy sortBy, int pageNumber, int pageSize)
	{
		if (existsTab(tabName))
		{
			if (!removeCustomTab(tabName))
				return false;
		}

		return addCustomTab(tabName, actionType, creator, startDate, stopDate, tags, sortBy, pageNumber, pageSize);
	}
	
	public 	boolean removeCustomTab(String tabName)
	{
	  try
	  {
			if (!_customCategories.has("categories"))
				return false;

			JSONArray categories = _customCategories.getJSONArray("categories");
			
			if (categories.length()==0)
				return false;
			
			JSONArray updatedCategories = new JSONArray();
			
			for (int i=0;i<categories.length();i++)
			{
				if (!categories.getJSONObject(i).getString("tabname").equalsIgnoreCase(tabName))
					updatedCategories.put(categories.getJSONObject(i));
			}
			
			_customCategories.remove("categories");
			_customCategories.put("categories", updatedCategories);
			saveToDisk();
		  
			return true;
	  }
	  catch (Exception e)
	  {
		  return false;
	  }
	  
	}
	
	public int getCustomTabsNumber()
	{
		try
		{
			loadFromDisk();
			return _customCategories.getJSONArray("categories").length();
		} catch (JSONException e)
		{
			return 0;
		}
	}

	public CustomTabData getCustomTabData(String tabName)
	{
		int tabIndex = findTab(tabName); 
		if (tabIndex!= -1)
		{
			return getCustomTabData(tabIndex);
		}
		else
		{
			return null;
		}
	}
	
	public CustomTabData getCustomTabData(int index)
	{
		try
		{
			JSONArray categories = _customCategories.getJSONArray("categories");
			JSONObject item = categories.getJSONObject(index);

			SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");

			CustomTabData tabData = new CustomTabData();

			tabData.setTabName(item.getString("tabname"));
			tabData.setActionType(Enum.valueOf(Type.class, item.getString("action")));

			if (item.has("creator"))
				tabData.setCreator(item.getString("creator"));

			if (item.has("startdate") && item.getString("startdate") != null && item.getString("startdate").length()>0)
				tabData.setStartDate(formatter.parse(item.getString("startdate")));

			if (item.has("stopdate") && item.getString("stopdate") != null && item.getString("stopdate").length()>0)
				tabData.setStopDate(formatter.parse(item.getString("stopdate")));

			JSONArray tags = item.getJSONArray("tags");
			if (tags != null && tags.length() > 0)
			{
				String[] tagsArray = new String[tags.length()];

				for (int i = 0; i < tags.length(); i++)
					tagsArray[i] = tags.getString(i);

				tabData.setTags(tagsArray);

			}

			if (item.has("sortby"))
				tabData.setSortBy(Enum.valueOf(SortBy.class, item
						.getString("sortby")));

			if (item.has("pagenumber"))
				tabData.setPageNumber(item.getInt("pagenumber"));

			if (item.has("pagesize"))
				tabData.setPageSize(item.getInt("pagesize"));

			return tabData;

		} catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}

	}

	public boolean existsTab(String tabName) 
	{
		return (findTab(tabName) != -1);
	}
	
 	private int findTab(String tabName)
 	{
 		try
		{
			if (!_customCategories.has("categories"))
				return -1;

			JSONArray categories = _customCategories.getJSONArray("categories");

			if (categories.length()==0)
				return -1;

			for (int i=0;i<categories.length();i++)
			{
				if (categories.getJSONObject(i).getString("tabname").equalsIgnoreCase(tabName))
					return i;
			}
			return -1;
		}
		catch (Exception e)
		{
			return -1;
		}
 	}
	
	private void loadFromDisk()
	{
		try
		{

			File inputfile = _context.getFileStreamPath("customcategories.data");
		
			if (!inputfile.exists())
			{
				_customCategories = new JSONObject();
				return;
			}
			
	        DataInputStream inputStream = new DataInputStream(_context.openFileInput("customcategories.data"));
			String savedCategories = inputStream.readUTF();
			
			_customCategories = new JSONObject(savedCategories);

			inputStream.close();

		} catch (Exception e)
		{
			_customCategories = new JSONObject();
		}

	}

	private void saveToDisk()
	{
		try
		{
			// erase old data and store the new one
			File outputfile = _context.getFileStreamPath("customcategories.data");
			if (outputfile.exists())
			{
				outputfile.delete();
				outputfile.createNewFile();
			}

			DataOutputStream outputStream = new DataOutputStream(_context.openFileOutput("customcategories.data", android.content.ContextWrapper.MODE_PRIVATE));
			
			String dataToWrite = _customCategories.toString();
			outputStream.writeUTF(dataToWrite);
			outputStream.close();

		} catch (FileNotFoundException e)
		{

			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	private JSONObject createTabData(String tabName, Type actionType,
			String creator, Date startDate, Date stopDate, String tags,
			SortBy sortBy, int pageNumber, int pageSize)
	{

		JSONObject tabData = new JSONObject();

		try
		{
			SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");

			tabData.put("tabname", tabName);
			tabData.put("action", actionType.name());
			if (creator != null) tabData.put("creator", creator);

			if (startDate != null)
				tabData.put("startdate", formatter.format(startDate));

			if (stopDate != null)
				tabData.put("stopdate", formatter.format(stopDate));

			JSONArray tagsArray = new JSONArray();
			if (tags != null)
			{
				String[] thetags = tags.split(" ");
				for (String tag : thetags)
					tagsArray.put(tag);
			}

			tabData.put("tags", tagsArray);

			if (sortBy != null) tabData.put("sortby", sortBy.name());

			tabData.put("pagenumber", pageNumber);
			tabData.put("pagesize", pageSize);

		} catch (JSONException e)
		{
			e.printStackTrace();
			return null;

		} catch (NullPointerException e)
		{
			e.printStackTrace();
			return null;
		}

		return tabData;

	}
	
	private JSONObject createTabData(String tabName, Type actionType,
			String creator, String startDate, String stopDate, String tags,
			SortBy sortBy, int pageNumber, int pageSize)
	{

		JSONObject tabData = new JSONObject();

		try
		{

			tabData.put("tabname", tabName);
			tabData.put("action", actionType.name());
			if (creator != null) 
				tabData.put("creator", creator);

			if (startDate != null)
				tabData.put("startdate", startDate);

			if (stopDate != null)
				tabData.put("stopdate", stopDate);

			JSONArray tagsArray = new JSONArray();
			if (tags != null && tags.length()>0 && !tags.equalsIgnoreCase("") && !tags.equalsIgnoreCase(" "))
			{
				String[] thetags = tags.split(" ");
				for (String tag : thetags)
					tagsArray.put(tag);
			}

			tabData.put("tags", tagsArray);

			if (sortBy != null) tabData.put("sortby", sortBy.name());

			tabData.put("pagenumber", pageNumber);
			tabData.put("pagesize", pageSize);

		} catch (JSONException e)
		{

			e.printStackTrace();
			return null;

		} catch (NullPointerException e)
		{
			e.printStackTrace();
			return null;
		}

		return tabData;

	}
}
